feat(layout): add .sf-cq and refactor .sf-equal to RAM pattern - #339
Conversation
Add .sf-cq — a lightweight container-type: inline-size scope for enabling anonymous @container queries without .sf-container's max-width and centering. Addresses the API trap where sf-grid-cols-* ratio grids silently broke when no container ancestor was present. Refactor .sf-equal from a fixed-count grid (repeat(N, 1fr)) to the RAM pattern (repeat(auto-fit, minmax(min(var(--sf-equal-min-col), 100%), 1fr))). Columns now wrap intrinsically — no @container or @media required. The --sf-equal-cols token is replaced by --sf-equal-min-col and four sized presets (--sf-equal-min-col-2/3/4/6) in tokens.layout.css. BREAKING: --sf-equal-cols is removed. Update custom overrides to --sf-equal-min-col: <width> (e.g. 14rem for a ~4-column layout). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu
…, color @Property, radius-2xs, equal tokens macros.css: add overflow-x: auto fallback before overflow-inline: auto in .sf-prose table (Safari < 18.2 compat — last missing instance). tokens.css: register computed color tokens (--sf-color-primary, --sf-color-secondary, -tertiary, -action, -neutral, -base, -success, -warning, -error, -info, -danger) with @Property (initial-value = light mode) and add :root mirrors. Fixes the @supports dependency chain: in browsers supporting oklch(from) + sign() but NOT light-dark(), these tokens now resolve to valid light-mode colors rather than being undefined. User overrides to --sf-color-X or --sf-color-X-light always take precedence. tokens.css: add --sf-radius-2xs: calc(1px * var(--sf-radius-scale)) to complete the radius scale symmetry with text/space (2xs→4xl). Update token inventory comment to include 2xs. tokens.layout.css: correct --sf-equal-min-col-4 (13rem → 16rem) and --sf-equal-min-col-6 (9rem → 10rem) so the RAM-pattern grid produces ~4 and ~6 columns at a standard 72rem container, matching modifier intent. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu
…rdcoded values The :root mirror for computed color tokens (--sf-color-primary etc.) must point to var(--sf-color-X-light) — not a hardcoded oklch value — so user overrides to --sf-color-primary-light are respected in browsers lacking light-dark() support. The @Property initial-value remains hardcoded (CSS spec requirement) and only activates when absolutely no declaration exists. The :root mirror is the effective default and the actual user-customisable path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu
|
Warning Review limit reached
More reviews will be available in 42 minutes and 34 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughFour core CSS files and comprehensive generated documentation are updated: ChangesCSS Token and Layout Primitive Updates
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
core/macros.css (1)
75-75:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd
overflow-x: revertto match the new fallback property.Line 50 now declares both
overflow-x: auto(Safari < 18.2 fallback) andoverflow-inline: auto. The.sf-not-prosereset at line 75 revertsoverflow-inlinebut omitsoverflow-x, so tables inside.sf-prose .sf-not-prosewill still scroll horizontally in Safari < 18.2—contradicting.sf-not-prose's documented purpose to fully reset prose styles.🛠️ Proposed fix to add the missing revert
- .sf-prose .sf-not-prose table { margin-block: 0; display: revert; overflow-inline: revert; inline-size: revert; max-inline-size: revert; } + .sf-prose .sf-not-prose table { margin-block: 0; display: revert; overflow-x: revert; overflow-inline: revert; inline-size: revert; max-inline-size: revert; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@core/macros.css` at line 75, The .sf-not-prose table rule at line 75 reverts overflow-inline but is missing overflow-x: revert. Since line 50 declares both overflow-x: auto (as a Safari < 18.2 fallback) and overflow-inline: auto, the .sf-not-prose reset must include both properties to fully revert prose styles. Add overflow-x: revert to the existing list of revert declarations in the .sf-not-prose table selector to ensure tables inside .sf-prose .sf-not-prose have both overflow properties consistently reset.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@core/macros.css`:
- Line 75: The .sf-not-prose table rule at line 75 reverts overflow-inline but
is missing overflow-x: revert. Since line 50 declares both overflow-x: auto (as
a Safari < 18.2 fallback) and overflow-inline: auto, the .sf-not-prose reset
must include both properties to fully revert prose styles. Add overflow-x:
revert to the existing list of revert declarations in the .sf-not-prose table
selector to ensure tables inside .sf-prose .sf-not-prose have both overflow
properties consistently reset.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: eb01024f-2786-4868-93b9-fd6f462c896a
📒 Files selected for processing (4)
core/layout.csscore/macros.csscore/tokens.csscore/tokens.layout.css
Registering --sf-color-* (computed tokens) as <color> via @Property caused child [data-theme="dark"] elements to inherit :root's resolved LIGHT color instead of computing the dark override. The typed property prevented var(--sf-color-X-dark, oklch(from var(--sf-color-X-light) ...)) from resolving correctly on child elements. Removing these @Property blocks restores unregistered custom-property behavior: raw text inheritance, correct theme scoping on nested elements, and baseline tests matching raw light-dark()/oklch() text values. The -light source tokens keep their @Property <color> registration (needed for @Property animation and typed transitions). Computed tokens are plain custom properties resolved by the :root mirrors block. Also fixes: - sf-equal 3-col layout: --sf-equal-min-col-3 18rem → 15rem (900px ÷ 3 fit) - overflow-x/overflow-inline ordering in .sf-prose .sf-not-prose table - Add .sf-cq demo to docs/demo.html (coverage test) - Update token-api snapshot: remove --sf-equal-cols, add new equal/radius tokens - Rebuild registry, dist badges, and all generated docs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
docs/api-index.json (1)
2124-2126: ⚡ Quick winDescription-value mismatch for status color tokens.
The
light-dark()function became baseline-available in May 2024, so fallback definitions are still important for compatibility. The description states these tokens "resolve to the -light source token" and are "Plain :root mirrors," but thevaluefield shows the fulllight-dark(...)formula with auto-dark derivation.This appears to reflect that the source CSS defines both a
:rootfallback (e.g.,--sf-color-action: var(--sf-color-action-light)) and an@supportsoverride withlight-dark(). The metadata is extracting the@supportsvalue while describing the:rootbehavior, which may confuse API consumers.If this is auto-generated, consider whether the generation logic should:
- Show both values (fallback + override), or
- Clarify in the description that the value shown is the modern/preferred definition
Also applies to: 3123-3125, 4557-4559, 4731-4733, 4905-4907, 5340-5342, 6368-6370, 7425-7427, 8482-8484, 8656-8658, 10206-10208
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/api-index.json` around lines 2124 - 2126, For the status color tokens (including all instances listed in "Also applies to"), there is a mismatch between the description and the value field. The description states these tokens resolve to the -light source token as "Plain :root mirrors," but the value field shows the full light-dark() formula with auto-dark derivation. Update the description for each affected token to clarify that the value shown represents the modern preferred definition using light-dark() for browsers where it is available, while acknowledging that fallback behavior may differ for older browser support. Apply this clarification consistently across all affected token entries.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/api-index.json`:
- Around line 16510-16511: The description for the `--sf-radius-2xs` token entry
is incorrectly discussing the behavior of `--sf-radius-full` (mentioning
pills/circles and topological constants) instead of describing `--sf-radius-2xs`
itself. Replace the description to accurately explain that `--sf-radius-2xs` is
the smallest radius token (extra-extra-small) and that, unlike
`--sf-radius-full`, it IS scaled by the `--sf-radius-scale` variable. Remove all
references to `--sf-radius-full`, pills, circles, and the topological constant
concept from this description field.
---
Nitpick comments:
In `@docs/api-index.json`:
- Around line 2124-2126: For the status color tokens (including all instances
listed in "Also applies to"), there is a mismatch between the description and
the value field. The description states these tokens resolve to the -light
source token as "Plain :root mirrors," but the value field shows the full
light-dark() formula with auto-dark derivation. Update the description for each
affected token to clarify that the value shown represents the modern preferred
definition using light-dark() for browsers where it is available, while
acknowledging that fallback behavior may differ for older browser support. Apply
this clarification consistently across all affected token entries.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 11141f5c-54d9-46c6-ae1e-f3121c4bdab6
⛔ Files ignored due to path filters (2)
dist/badge-essential.jsonis excluded by!**/dist/**dist/badge-optimal.jsonis excluded by!**/dist/**
📒 Files selected for processing (13)
configurator/src/data/api-index.generated.jsoncore/macros.csscore/tokens.csscore/tokens.layout.cssdocs/api-index.jsondocs/api-index.mddocs/classes.mddocs/demo.htmldocs/registry.jsondocs/token-index.jsondocs/token-index.mddocs/tokens.mdtests/token-api.snapshot.json
✅ Files skipped from review due to trivial changes (5)
- docs/demo.html
- docs/token-index.json
- docs/token-index.md
- docs/api-index.md
- configurator/src/data/api-index.generated.json
🚧 Files skipped from review as they are similar to previous changes (1)
- core/tokens.layout.css
…ia -dark source tokens Registers computed color tokens (--sf-color-primary etc.) as @Property <color> to enable CSS transitions between light and dark values when [data-theme] toggles. The previous attempt broke child-element dark theming because var(--sf-color-X-dark, oklch(from var(--sf-color-X-light) ...)) fails type-checking when the outer var() has no match and the fallback contains a nested var() reference in a registered <color> property. Fix: declare --sf-color-X-dark as plain :root tokens inside the @supports (color: oklch(...)) block in themes.css, using the same relative color formulas that were previously hidden in the var() fallbacks. [data-theme="dark"] now assigns var(--sf-color-X-dark) directly — a simple var reference that type-checks correctly on child elements. Dark values auto-compute from -light via relative color syntax, and --sf-color-X-dark is now a first-class user-overridable token. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu
The @Property registrations for --sf-color-{action,base,danger,error,info, neutral,primary,secondary,success,tertiary,warning}-dark in core/tokens.css are now surfaced in the TOKEN_FILES scan. Update the locked snapshot so the token-api spec does not flag them as unexpected additions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu
…d update baselines Add @Property <color> registrations for all 11 -dark source tokens (primary, secondary, tertiary, action, neutral, base, success, warning, error, info, danger) so Chromium resolves them to typed absolute OKLCH values on :root. Without this, child elements with [data-theme="dark"] inherit the raw formula text and Chrome fails multi-level var() substitution inside registered <color> properties, producing light colors in dark sections. Also: - Add --sf-radius-2xs to docs/token-annotations.json (configurator sync) - Update tests/baseline-modern.json to reflect registered @Property behavior (source tokens now return absolute OKLCH; derived tokens return formula text with substituted absolute OKLCH for the registered vars) - Rebuild dist/ and docs/ (api-index, token-index, registry, badge scores) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu
…dark"] Unregistered custom properties bake their var() substitutions at the element that declares them (here: :root in light mode). Child elements scoped with [data-theme="dark"] inherit the pre-substituted light values for --sf-color-bg, --sf-color-inset, --sf-color-raised, --sf-color-overlay, --sf-color-inverse and all --sf-color-text--on-* tokens, so neither the demo a11y-panel probes nor real scoped dark sections showed correct dark surface colours. Fix: explicitly re-declare every affected token inside [data-theme="dark"] so the cascade produces the correct dark values at that element's scope rather than inheriting the root's baked light text. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@configurator/src/data/api-index.generated.json`:
- Around line 2286-2288: The "group" and "description" fields for non-status
color tokens (primary, secondary, tertiary, base, neutral, and action) are
incorrectly labeled as "STATUS COLORS (-light source tokens)" with descriptions
referencing only status colors. This mislabeling occurs across multiple entries
in the file. For each of the listed line ranges, update the "group" field to use
appropriate taxonomy that reflects these are general color tokens rather than
status-specific tokens, and update the corresponding "description" field to
remove status-specific language and accurately describe the actual color
category being defined.
In `@core/themes.css`:
- Around line 289-304: The on-color text tokens like
--sf-color-text--on-primary, --sf-color-text--on-secondary, and all related
on-color variables are only declared within the [data-theme="dark"] block. When
a light-themed section exists within a dark-mode page, these tokens will inherit
the dark-mode-computed values, causing incorrect contrast. Add a corresponding
[data-theme="light"] block immediately after the dark theme block that
re-declares all the same on-color token variables with values appropriate for
light theme, using a sign logic that inverts the condition from the dark theme
block to ensure correct text contrast in light mode.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: ec1a182b-48f2-4733-abac-6d93faa2767e
⛔ Files ignored due to path filters (2)
dist/badge-essential.jsonis excluded by!**/dist/**dist/badge-optimal.jsonis excluded by!**/dist/**
📒 Files selected for processing (12)
configurator/src/data/api-index.generated.jsoncore/themes.csscore/tokens.cssdocs/api-index.jsondocs/api-index.mddocs/registry.jsondocs/token-annotations.jsondocs/token-index.jsondocs/token-index.mddocs/tokens.mdtests/baseline-modern.jsontests/token-api.snapshot.json
✅ Files skipped from review due to trivial changes (5)
- docs/token-annotations.json
- docs/token-index.md
- docs/registry.json
- docs/token-index.json
- docs/api-index.md
…ions and correct -dark token group Symmetric fix for the same baking problem solved in [data-theme="dark"]: when :root is in dark mode (OS preference or explicit attribute) and a child section uses [data-theme="light"], surface tokens (--sf-color-bg etc.) and on-color text tokens (--sf-color-text--on-*) inherited the dark-mode-baked values from :root. Add explicit re-declarations of all five surface tokens and all eleven on-color tokens to [data-theme="light"] so scoped light sections always derive from the correct light brand colors regardless of root mode. Also fixes mislabeled group metadata for the eleven --sf-color-*-dark @Property tokens: split the multiline comment in tokens.css into a recognised single-line sub-header so gen-api-index.js assigns the group "DARK SOURCE TOKENS (-dark, animatable)" instead of inheriting the previous "STATUS COLORS (-light source tokens)" banner. Added matching _groups entry to token-annotations.json. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu
Add .sf-cq — a lightweight container-type: inline-size scope for
enabling anonymous @container queries without .sf-container's
max-width and centering. Addresses the API trap where sf-grid-cols-*
ratio grids silently broke when no container ancestor was present.
Refactor .sf-equal from a fixed-count grid (repeat(N, 1fr)) to the
RAM pattern (repeat(auto-fit, minmax(min(var(--sf-equal-min-col), 100%), 1fr))).
Columns now wrap intrinsically — no @container or @media required.
The --sf-equal-cols token is replaced by --sf-equal-min-col and four
sized presets (--sf-equal-min-col-2/3/4/6) in tokens.layout.css.
BREAKING: --sf-equal-cols is removed. Update custom overrides to
--sf-equal-min-col: (e.g. 14rem for a ~4-column layout).
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu
Summary by CodeRabbit
Release Notes
.sf-cqto create an inline-size container-query scope..sf-equaland variants) to be intrinsically responsive.--sf-radius-2xsfor finer corner-radius control.